package biblio;

import java.io.Serializable;
import java.util.GregorianCalendar;
import java.util.HashMap;

/**
 * Classe de gestion d'une biblioth�que
 * @author IUT, refactor� par E. Ceret
 * @version 2.0
  *
 */
public class Bibliotheque implements Serializable {

	// ************************************************************************************************************
	// Constantes
	// ************************************************************************************************************

	private static final long serialVersionUID = 7024815135236060724L;
	
	// ************************************************************************************************************
	// Attributs
	// ************************************************************************************************************

	private int _derNumLecteur; // Dernier n� de lecteur (permet de g�n�rer automatiquement l'id d'un lecteur)

	// Attributs d'Association
	private HashMap<Integer, Lecteur> _lecteurs; // Ensemble des lecteurs
	private HashMap<Integer, Auteur> _auteurs; // Ensemble des auteurs
	private HashMap<String, Ouvrage> _ouvrages; // Ensemble des ouvrages
	private HashMap<String, MotCle> _motscle; // Ensemble des mots clé

	// ************************************************************************************************************
	// Constructeur
	// ************************************************************************************************************

	/**
	 * Constructeur.
	 */
	public Bibliotheque() {
		this.setLecteurs(new HashMap<Integer, Lecteur>());
		this.setOuvrages(new HashMap<String, Ouvrage>());
		this.setMotsCle(new HashMap<String, MotCle>());
		this.setDerNumLecteur(0);
	} // Fin Bibliotheque

	// ************************************************************************************************************
	// M�thodes priv�es
	// ************************************************************************************************************

	// ------------------------------------------------------------------------------------------------------------
	// Affecteurs
	
	/**
	 * @param numLecteur valeur � affecter au dernier n� de lecteur
	 */
	private void setDerNumLecteur(int numLecteur) {
		_derNumLecteur = numLecteur;
	}

	/**
	 * @param lecteurs hashtable de lecteurs � affecter
	 */
	public void setLecteurs(HashMap<Integer, Lecteur> lecteurs) {
		_lecteurs = lecteurs;
	}

	/**
	 * @param ouvrages hashtable d'ouvrages � affecter
	 */
	public void setOuvrages(HashMap<String, Ouvrage> ouvrages) {
		_ouvrages = ouvrages;
	}
	

	/**
	 * @param ouvrages hashtable des mots cle � affecter
	 */
	public void setMotsCle(HashMap<String, MotCle> motcles) {
		_motscle = motcles;
	}
		
	
	/**
	 * Ajoute un lecteur � l'ensemble des lecteurs.
	 * @param lecteur Lecteur � ajouter
	 * @param numero num�ro de ce lecteur
	 */
	private void lierLecteur(Lecteur lecteur, int numero) {
		this.getLecteurs().put(numero, lecteur);
	} // Fin lierLecteur

	/**
	 * Ajoute un ouvrage � l'ensemble des ouvrages.
	 * @param ouvrage Ouvrage � ajouter
	 * @param isbn code ISBN de cet ouvrage
	 */
	private void lierOuvrage(Ouvrage ouvrage, String isbn) {
		this.getOuvrages().put(isbn, ouvrage);
	} // Fin lierOuvrage
	

	/**
	 * Ajoute un ouvrage � l'ensemble des ouvrages.
	 * @param ouvrage Ouvrage � ajouter
	 * @param isbn code ISBN de cet ouvrage
	 */
	private void lierMotCle(MotCle motcle, String motcl) {
		this.getMotsCle().put(motcl, motcle);
	} // Fin lierOuvrage


	// ************************************************************************************************************
	// M�thodes publiques
	// ************************************************************************************************************

	// ------------------------------------------------------------------------------------------------------------
	// Accesseurs
	
	/**
	 * @return n� du dernier lecteur
	 */
	public int getDerNumLecteur() {
		return _derNumLecteur;
	}

	/**
	 * @return ensemble des lecteurs
	 */
	public HashMap<Integer, Lecteur> getLecteurs() {
		return _lecteurs;
	}
	
	/**
	 * @return ensemble des auteurs
	 */
	public HashMap<Integer, Auteur> getAuteurs() {
		return _auteurs;
	}

	/**
	 * @return ensemble des ouvrages
	 */
	public HashMap<String, Ouvrage> getOuvrages() {
		return _ouvrages;
	}
	

	/**
	 * @return ensemble des mots clé
	 */
	public HashMap<String, MotCle> getMotsCle() {
		return _motscle;
	}

	/**
	 * Acc�s � un lecteur par son num�ro
	 * @param numero num�ro du lecteur cherch�
	 * @return le lecteur qui a le num�ro indiqu�
	 */
	public Lecteur getLecteur(int numero) {
		return this.getLecteurs().get(numero);
	} // Fin getLecteur
	
	/**
	 * Acc�s � un auteur par son num�ro
	 * @param  chaine représentant le nom ou le prénom de l'auteur cherch�
	 * @return le Auteur qui a le num�ro indiqu�
	 */
	public Auteur getAuteur(String nom, String prenom ) {
		
		Auteur retour = null;
		
		for (int i =0; Auteur auteur : this.getAuteurs().get(i); i++)
		 		
		if(nom == this.getAuteurs().get(i).getnomAuteur() && prenom == this.getAuteurs().get(i).getprenomAuteur())
		{	retour = this.getAuteurs().get(i);
		}
		
		
		return retour;
	} // Fin getAuteur

	/**
	 * Acc�s � un ouvrage par son num�ro ISBN
	 * @param isbn le code ISBN de l'ouvrage cherch�
	 * @return l'ouvrage qui a l'ISBN indiqu�
	 */
	public Ouvrage getOuvrage(String isbn) {
		return this.getOuvrages().get(isbn);
	} // Fin getOuvrage
	
	/**
	 * Accès à un motcle par le mot cle
	 * @param le mot cle
	 * @return le mot cle
	 */
	public MotCle getMotCle(String motcle) {
		return this.getMotsCle().get(motcle);
	} // Fin getMotCle

	// ------------------------------------------------------------------------------------------------------------
	// Traitements

	/**
	 * Cr�ation d'un lecteur.
	 * @param nom		nom du lecteur
	 * @param prenom	pr�nom du lecteur
	 * @param adresse	adresse du lecteur
	 * @param age		�ge du lecteur
	 * @return le lecteur instanci�
	 */
	public Lecteur nouveauLecteur(String nom, String prenom, String adresse, int age) {

		int numero = this.genererNumLecteur();
		
		// Creation de l'instance lect
		Lecteur lecteur = new Lecteur(numero, nom, prenom, adresse, age);
		
		// Ajout du lecteur dans l'ensemble des lecteurs
		this.lierLecteur(lecteur, numero);

		return lecteur;
	} // Fin nouveauLecteur

	/**
	 * Cr�ation d'un nouvel ouvrage.
	 * @param isbn		num�ro ISBN de l'ouvrage
	 * @param titre		titre de l'ouvrage
	 * @param auteur	auteur de l'ouvrage
	 * @param editeur	�diteur de l'ouvrage
	 * @param dateEdition	date d'�dition de l'ouvrage
	 * @return	l'ouvrage instanci�
	 */
	public Ouvrage nouvelOuvrage(String isbn, String titre, String editeur, GregorianCalendar dateParution) {
		// Instanciation de l'ouvrage
		Ouvrage ouvrage = new Ouvrage(isbn, titre, editeur, dateParution);
		// Ajout de l'ouvrage dans l'ensemble des ouvrages
		this.lierOuvrage(ouvrage, isbn);
		
		return ouvrage;
	} // Fin nouvelOuvrage
	
	/**
	 * Cr�ation d'un nouveau mot cle.
	 * @param motcle		mot clé
	 * @return	le mot clé instancié
	 */
	public MotCle nouveauMotCle(String motcl) {
		// Instanciation du mot clé
		MotCle motcle = new MotCle(motcl);
		// Ajout du mot clé dans l'ensemble des mots clé
		this.lierMotCle(motcle, motcl);
		
		return motcle;
	} // Fin nouveauMotCle
	
	/**
	 * Creation d'un nouvel auteur d'un ouvrage.
	 * @param ouvrage			ouvrage dont on cr�e un auteur
	 * @param nomauteur			nom d'aun auteur
	 *  @param prenomauteur		prenom d'un auteur
	 */
	public void nouvelAuteur(Ouvrage ouvrage, String nomAuteur, String prenomAuteur) {
		
		// Cr�ation d'un auteur dans l'ouvrage.
		 ouvrage.ajouterAuteur(nomAuteur,  prenomAuteur);
	} // Fin nouvelAuteur

	/**
	 * Creation d'un nouvel exemplaire d'un ouvrage.
	 * @param ouvrage			ouvrage dont on cr�e un exemplaire
	 * @param dateReception		date � laquelle le nouvel exemplaire a �t� re�u
	 */
	public void nouvelExemplaire(Ouvrage ouvrage, GregorianCalendar dateReception) {
		
		// Cr�ation d'un exemplaire dans l'ouvrage.
		ouvrage.ajouterExemplaire(dateReception);
	} // Fin nouvelExemplaire
	
	/**
	 * Change le statut d'un exemplaire d'ouvrage.
	 * @param exemplaire l'exemplaire dont le statut doit changer
	 * @param statut le nouveau statut � affecter � l'exemplaire
	 */
	public void modifStatutExemplaire(Exemplaire exemplaire, int statut) {
		
		// Modification du statut de l'exemplaire
		exemplaire.setStatut(statut);
	} // modifStatutExemplaire

	/**
	 * G�n�re un n� de lecteur non encore affect�
	 * @return un entier repr�sentant un n� de lecteur (le dernier + 1) 
	 */
	private int genererNumLecteur() {
		this.setDerNumLecteur(this.getDerNumLecteur() + 1);
		return this.getDerNumLecteur();
	} // Fin genererNumLecteur
	
} // Fin Classe Bibliotheque
